package com.google.code.timetrail.tests;

import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.Before;
import org.junit.Test;

import com.google.code.timetrail.backend.Control;
import com.google.code.timetrail.backend.Doctor;
import com.google.code.timetrail.backend.Engine;
import com.google.code.timetrail.backend.Engineer;
import com.google.code.timetrail.backend.Entrepreneur;
import com.google.code.timetrail.backend.FluxCapacitor;
import com.google.code.timetrail.backend.Food;
import com.google.code.timetrail.backend.FuelCell;
import com.google.code.timetrail.backend.HullPart;
import com.google.code.timetrail.backend.Inventory;
import com.google.code.timetrail.backend.Item;
import com.google.code.timetrail.backend.Money;
import com.google.code.timetrail.backend.Nutritionist;
import com.google.code.timetrail.backend.Person;
import com.google.code.timetrail.backend.Place;
import com.google.code.timetrail.backend.River;
import com.google.code.timetrail.backend.TimeBulletBill;
import com.google.code.timetrail.backend.TimeSuit;

/**
 * JUnit tests for river crossing
 * 
 * @author Utkarsh Pandey
 */

public class RiverTest {
	private static final int TEST_FOOD_AMOUNT = 30000000;

	private Control control;

	private Person doctor;
	private Person engineer;
	private Person entrepreneur;
	private Person nutritionist;

	private Item engine;
	private Item fluxCapacitor;
	private Item fuelCell;
	private Item hullPart;
	private Item money;
	private Item timeBulletBill;
	private Item timeSuit;

	private Inventory fullInventory;

	private Place[] places;

	@Before
	public void setUpRiver() {
		doctor = new Doctor();
		engineer = new Engineer();
		entrepreneur = new Entrepreneur();
		nutritionist = new Nutritionist();

		engine = new Engine();
		fluxCapacitor = new FluxCapacitor();
		fuelCell = new FuelCell();
		hullPart = new HullPart();
		money = new Money();
		timeBulletBill = new TimeBulletBill();
		timeSuit = new TimeSuit();

		control = new Control();
		ArrayList<Person> members = new ArrayList<Person>();
		members.add(doctor);
		members.add(engineer);
		members.add(entrepreneur);
		members.add(nutritionist);
		control.setMembers(members);

		fullInventory = new Inventory();

		fullInventory.setInvWeight(0);
		fullInventory
				.addItem(engine.getMaxAmount(), fullInventory.getEngines());
		fullInventory.addItem(fluxCapacitor.getMaxAmount(),
				fullInventory.getFCapacitors());
		fullInventory.addItem(TEST_FOOD_AMOUNT, fullInventory.getFood());
		fullInventory.addItem(fuelCell.getMaxAmount(),
				fullInventory.getFuelCells());
		fullInventory.addItem(hullPart.getMaxAmount(),
				fullInventory.getHullParts());
		fullInventory.addItem(money.getMaxAmount(), fullInventory.getMoney());
		fullInventory.addItem(timeBulletBill.getMaxAmount(),
				fullInventory.getMoney());
		fullInventory.addItem(timeSuit.getMaxAmount(),
				fullInventory.getTimeSuits());

		control.setInv(fullInventory);

		places = Place.values();
	}

	@Test
	public void testTakeFerryDoctor() {
		control.setPlayer(doctor);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			String ferry = river.takeFerry();
			assertFalse(
					"Not able to take Ferry",
					ferry.equals("You don't have enough money to make it across!"));
		}

		river = new River(control, control.getCurrentPlace());
		assertEquals(40, river.getFerryPrice());

		control.getPlayer().intializeSkills();

		assertEquals(40, river.getFerryPrice());
	}

	@Test
	public void testFordDoctor() {
		control.setPlayer(doctor);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			if (p.getName().equals("Kansas River")
					|| p.getName().equals("Snake River Crossing"))
				assertEquals(0.0, (double) passed / 10000.0, 0.45);
			else if (p.getName().equals("Big Blue"))
				assertEquals(.05, (double) passed / 10000.0, 0.45);
			else
				assertEquals(.7, (double) passed / 10000.0, 0.45);
		}
	}
	
	@Test
	public void testCaulkDoctor() {
		control.setPlayer(doctor);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			assertEquals(.35, (double) passed / 10000.0, 0.55);
		}
	}

	@Test
	public void testTakeFerryEngineer() {
		control.setPlayer(engineer);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			String ferry = river.takeFerry();
			assertFalse(
					"Not able to take Ferry",
					ferry.equals("You don't have enough money to make it across!"));
		}

		river = new River(control, control.getCurrentPlace());
		assertEquals(40, river.getFerryPrice());

		control.getPlayer().intializeSkills();

		assertEquals(40, river.getFerryPrice());
	}

	@Test
	public void testFordEngineer() {
		control.setPlayer(engineer);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			if (p.getName().equals("Kansas River")
					|| p.getName().equals("Snake River Crossing"))
				assertEquals(0.0, (double) passed / 10000.0, 0.45);
			else if (p.getName().equals("Big Blue"))
				assertEquals(.05, (double) passed / 10000.0, 0.45);
			else
				assertEquals(.7, (double) passed / 10000.0, 0.45);
		}
	}

	@Test
	public void testCaulkEngineer() {
		control.setPlayer(engineer);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			assertEquals(.35, (double) passed / 10000.0, 0.55);
		}
	}
	
	@Test
	public void testTakeFerryEntrepreneur() {
		control.setPlayer(entrepreneur);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			String ferry = river.takeFerry();
			assertFalse(
					"Not able to take Ferry",
					ferry.equals("You don't have enough money to make it across!"));
		}

		river = new River(control, control.getCurrentPlace());
		assertEquals(40, river.getFerryPrice());

		control.getPlayer().intializeSkills();

		assertEquals(20, river.getFerryPrice());
	}

	@Test
	public void testFordEntrepreneur() {
		control.setPlayer(entrepreneur);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			if (p.getName().equals("Kansas River")
					|| p.getName().equals("Snake River Crossing"))
				assertEquals(0.0, (double) passed / 10000.0, 0.45);
			else if (p.getName().equals("Big Blue"))
				assertEquals(.05, (double) passed / 10000.0, 0.45);
			else
				assertEquals(.7, (double) passed / 10000.0, 0.45);
		}
	}

	@Test
	public void testCaulkEntrepreneur() {
		control.setPlayer(entrepreneur);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			assertEquals(.35, (double) passed / 10000.0, 0.55);
		}
	}

	@Test
	public void testTakeFerryNutritionist() {
		control.setPlayer(nutritionist);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			String ferry = river.takeFerry();
			assertFalse(
					"Not able to take Ferry",
					ferry.equals("You don't have enough money to make it across!"));
		}

		river = new River(control, control.getCurrentPlace());
		assertEquals(40, river.getFerryPrice());

		control.getPlayer().intializeSkills();

		assertEquals(40, river.getFerryPrice());
	}

	@Test
	public void testFordNutritionist() {
		control.setPlayer(nutritionist);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			if (p.getName().equals("Kansas River")
					|| p.getName().equals("Snake River Crossing"))
				assertEquals(0.0, (double) passed / 10000.0, 0.45);
			else if (p.getName().equals("Big Blue"))
				assertEquals(.05, (double) passed / 10000.0, 0.45);
			else
				assertEquals(.7, (double) passed / 10000.0, 0.45);
		}
	}
	
	@Test
	public void testCaulkNutritionist() {
		control.setPlayer(nutritionist);

		River river;
		for (Place p : places) {
			river = new River(control, p);
			int passed = 0;
			for (int i = 0; i < 10000; i++) {
				String ford = river.ford();
				if (ford.equals("You sucessfully made it across the time stream"))
					passed++;
			}

			assertEquals(.35, (double) passed / 10000.0, 0.55);
		}
	}
}
